package sharemem

import (
	"encoding/json"
	"server_cluster/common/gdconf"
	"server_cluster/common/logger"
	"server_cluster/common/protoc/pb"
	"slices"
)

type UserCodex struct {
	CodexList [1000]Codex // 图鉴列表
	//codexMap  *hashmap.HashMap[int32, *Codex] // 图鉴集合 在线数据
}

func (c UserCodex) MarshalJSON() ([]byte, error) {
	dbUserCodex := struct {
		CodexList []Codex // 图鉴列表
	}{}
	for _, codex := range c.CodexList {
		if !codex.IsUse() {
			continue
		}
		dbUserCodex.CodexList = append(dbUserCodex.CodexList, codex)
	}
	data, err := json.Marshal(dbUserCodex)
	if err != nil {
		return nil, err
	}
	return data, nil
}

func (c *UserCodex) UnmarshalJSON(data []byte) error {
	dbUserCodex := struct {
		CodexList []Codex // 图鉴列表
	}{}
	err := json.Unmarshal(data, &dbUserCodex)
	if err != nil {
		return err
	}
	for index, codex := range dbUserCodex.CodexList {
		c.CodexList[index] = codex
	}
	return nil
}

func (c *UserCodex) MemInit() {
	for i := 0; i < len(c.CodexList); i++ {
		c.CodexList[i].MemInit()
	}
}

type Codex struct {
	CodexId    int32 // 图鉴id
	RewardTake bool  // 是否领奖
	Param1     int32
	Param2     int32
	Param3     int32
}

func (c *Codex) IsUse() bool {
	return c.CodexId != 0
}

func (c *Codex) MemInit() {
	c.CodexId = 0
	c.RewardTake = false
	c.Param1 = 0
	c.Param2 = 0
	c.Param3 = 0
}

func (u *User) GetCodex(codexId int32) *Codex {
	for i := 0; i < len(u.UserCodex.CodexList); i++ {
		codex := &(u.UserCodex.CodexList[i])
		if codex.CodexId == codexId {
			return codex
		}
	}
	return nil
}

func (u *User) GetCodexList() []*Codex {
	list := make([]*Codex, 0)
	for i := 0; i < len(u.UserCodex.CodexList); i++ {
		codex := &(u.UserCodex.CodexList[i])
		if codex.CodexId == 0 {
			break
		}
		list = append(list, codex)
	}
	return list
}

func (u *User) AddCodex(codexId int32) *Codex {
	for i := 0; i < len(u.UserCodex.CodexList); i++ {
		codex := &(u.UserCodex.CodexList[i])
		if codex.CodexId != 0 {
			continue
		}
		codex.CodexId = codexId
		codex.RewardTake = false
		u.Add2codexMap(codex.CodexId, codex)
		return codex
	}
	logger.Error("no empty codex found")
	return nil
}

func (u *User) PacketCodexAllTypeData(codexIdList []int32) []*pb.CodexTypeData {
	codexTypeListMap := make(map[int32][]*Codex)
	for _, codex := range u.GetCodexList() {
		if codexIdList != nil && !slices.Contains[[]int32, int32](codexIdList, codex.CodexId) {
			continue
		}
		codexConfig := gdconf.GetCodexConfig(codex.CodexId)
		if codexConfig == nil {
			continue
		}
		codexList := codexTypeListMap[codexConfig.CodexType]
		if codexList == nil {
			codexList = make([]*Codex, 0)
		}
		codexList = append(codexList, codex)
		codexTypeListMap[codexConfig.CodexType] = codexList
	}
	pbCodexTypeDataList := make([]*pb.CodexTypeData, 0)
	for _type, codexList := range codexTypeListMap {
		pbCodexList := make([]*pb.CodexData, 0)
		for _, codex := range codexList {
			pbCodexList = append(pbCodexList, &pb.CodexData{
				CodexId:    codex.CodexId,
				RewardTake: codex.RewardTake,
			})
		}
		pbCodexTypeDataList = append(pbCodexTypeDataList, &pb.CodexTypeData{
			CodexList: pbCodexList,
			Type:      pb.CodexType(_type),
		})
	}
	return pbCodexTypeDataList
}
